package model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class Game {
	protected Map<Property, Object> properties;
	protected List<Agent> agents;
	
	public Game() {
		properties = new HashMap<Property, Object>();
	}
	
	public void Run() {
		for(int i=0 ; i < (int) getProperty(Property.GENERATIONS) ; i++) {
			output();
			interact();
		}
	}
	
	public boolean containsProperty(Property prop) {
		if (properties.containsKey(prop))
			return true;
		else
			return false;
	}
	
	public Object getProperty(Property prop) {
		if (properties.containsKey(prop))
			return properties.get(prop);
		
		return null;
	}
	
	public void setProperty(Property prop, Object value) {
		properties.put(prop, value);
	}
	
	/*
	 * This method is invoked every time the application starts, once.
	 * The required preparations for game to work need to be done here.
	 */
	public abstract void initialize();
	public abstract void interact();
	public abstract void reward();
	public abstract void reproduce();
	public abstract void output();
	
	protected Agent getRandomAgent() {
		return agents.get((int) (agents.size() * Math.random()));
	}
	
	protected void reward(List<Agent> agentList) {
		for (Agent a : agentList) {
			a.reward((int) getProperty(Property.BENEFIT));
		}
	}
	
	@Override
	public String toString() {
		return (String) (containsProperty(Property.GAME_NAME) ? getProperty(Property.GAME_NAME) : "Untitled Game");
	}
	
	public Object[][] getPropertiesArray() {
		List<Object[]> propsList = new ArrayList<Object[]>();
		
		for (Property entry : properties.keySet()) {
			Object[] pair = { entry.name(), getProperty(entry) };
			propsList.add(pair);
		}
		
		return propsList.toArray(new Object[][]{});
	}
}
